﻿
Imports System.Runtime.CompilerServices

Public Module tcp_pac_extensions
    Private Function deserialize(Of OT As toBytes)(ByVal i() As Byte, ByRef o As OT) As Boolean
        Dim oo() As fromBytes = Nothing
        Return _deserializer.deserialize(i, oo) AndAlso
               Not oo Is Nothing AndAlso
               oo.Length() = 1 AndAlso
               convertor.cast(Of OT)(oo(0), o)
    End Function

    Private Function deserialize(Of OT As toBytes)(ByVal i() As Byte, ByVal o As pointer(Of OT)) As Boolean
        Dim oo As OT = Nothing
        Return deserialize(i, oo) AndAlso eva(o, oo)
    End Function

    <Extension()> Public Function talk(Of IT As fromBytes, OT As toBytes) _
                                      (ByVal this As tcp_pac_talk,
                                       ByVal input As IT,
                                       ByVal output As pointer(Of OT)) As eventComb
        Dim i As bytes = Nothing
        Dim o As pointer(Of bytes) = Nothing
        o = New pointer(Of bytes)()
        If this Is Nothing OrElse input Is Nothing OrElse Not serialize(i, input) Then
            Return eventComb.failed()
        Else
            Dim ec As eventComb = Nothing
            ec = this.talk(i, o)
            Return New eventComb(Function() As Boolean
                                     Return waitfor(ec) AndAlso goto_next()
                                 End Function,
                                 Function() As Boolean
                                     If ec.end_result() Then
                                         Return deserialize(++o, output) AndAlso goto_end()
                                     Else
                                         Return False
                                     End If
                                 End Function)
        End If
    End Function

    Public Sub receive_async(Of IT As toBytes, OT As fromBytes) _
                            (ByVal input() As Byte,
                             ByVal output As pointer(Of bytes),
                             ByRef ec As eventComb,
                             ByVal d As _do(Of IT, pointer(Of OT), eventComb))
        assert(Not d Is Nothing)
        Dim i As IT = Nothing
        If deserialize(input, i) Then
            Dim o As pointer(Of OT) = Nothing
            o = New pointer(Of OT)()
            Dim dec As eventComb = Nothing
            dec = d(i, o)
            ec = New eventComb(Function() As Boolean
                                   Return waitfor(dec) AndAlso goto_next()
                               End Function,
                               Function() As Boolean
                                   If dec.end_result() Then
                                       Dim oo As bytes = Nothing
                                       Return serialize(oo, +o) AndAlso
                                              eva(output, oo) AndAlso
                                              goto_end()
                                   Else
                                       Return False
                                   End If
                               End Function)
        Else
            ec = eventComb.failed()
        End If
    End Sub

    Public Sub receive_sync(Of IT As toBytes, OT As fromBytes) _
                           (ByVal input() As Byte,
                            ByVal output As pointer(Of bytes),
                            ByRef result As Boolean,
                            ByVal d As _do(Of IT, OT, Boolean))
        assert(Not d Is Nothing)
        Dim i As IT = Nothing
        If deserialize(input, i) Then
            Dim o As OT = Nothing
            Dim oo As bytes = Nothing
            result = d(i, o) AndAlso
                     serialize(oo, o) AndAlso
                     eva(output, oo)
        Else
            result = False
        End If
    End Sub
End Module
